home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / SCROLL.ZIP / SCROLL.TXT
Encoding:
Text File  |  1996-04-26  |  12.5 KB  |  535 lines

  1.  
  2.  
  3.  
  4.       SSSSS   CCCCC  RRRRR    OOOOO  LL    LL    IIIIII NN    NN  GGGGG
  5.  
  6.      SS   SS CC   CC RR  RR  OO   OO LL    LL      II   NNN   NN GG   GG
  7.  
  8.      SS      CC      RR   RR OO   OO LL    LL      II   NNNN  NN GG
  9.  
  10.       SSSSS  CC      RR  RR  OO   OO LL    LL      II   NN NN NN GG
  11.  
  12.           SS CC      RRRRR   OO   OO LL    LL      II   NN  NNNN GG  GGG
  13.  
  14.      SS   SS CC   CC RR  RR  OO   OO LL    LL      II   NN   NNN GG   GG
  15.  
  16.       SSSSS   CCCCC  RR   RR  OOOOO  LLLLL LLLLL IIIIII NN    NN  GGGGG
  17.  
  18.  
  19.                     by Alec Thomas (Kestrel) of FORGE Software Australia
  20.  
  21.                                           (c9223826@cs.newcastle.edu.au)
  22.  
  23.  
  24.  
  25. ------------
  26.  
  27. INTRODUCTION
  28.  
  29. ------------
  30.  
  31. Okay, here it is fans (and air conditioners, open windows...geez I hate that
  32.  
  33. joke!), how to do scrolling using either X-mode (and associated variants) and
  34.  
  35. standard mode 13h (not hard but I thought I'd put it in anyway :) as well as
  36.  
  37. the basics of parallax scrolling...
  38.  
  39.  
  40. First things first - X-mode. Throughout this little dissertation, I'm going
  41.  
  42. to assume that you know the basics of X-mode (or mode-X or mode-Y or
  43.  
  44. whatever you want to call it) such as how to get into it, how to set the
  45.  
  46. offset register, etc. and just get on with the scrolling :) I'm not trying
  47.  
  48. to teach you X-mode, but SCROLLING!!
  49.  
  50.  
  51. One further thing. I'm not saying that the methods I'll explain below are
  52.  
  53. the best method of scrolling, I'm just showing how I got it to work myself
  54.  
  55. in the hope that someone out there can use it. Anyway, enough of this crap,
  56.  
  57. on with the STUFF!!!
  58.  
  59.  
  60. (just a little note, when I'm talking about rows, they number from 0-199 and
  61.  
  62. the same with columns (except 0-319), etc. unless otherwise stated)
  63.  
  64.  
  65. ********************************************************************************
  66.  
  67. *                               X-MODE SCROLLING                               *
  68.  
  69. ********************************************************************************
  70.  
  71. ------------------
  72.  
  73. VERTICAL SCROLLING
  74.  
  75. ------------------
  76.  
  77. Ok, this is the easiest form of scrolling using the VGA hardware...fast and
  78.  
  79. clean. The following example assumes you are using 320x200 X-mode with the
  80.  
  81. visible page starting at the top of the first page (offset 0).
  82.  
  83.  
  84. To scroll what is on the screen up off the top, you simply add 80 (decimal)
  85.  
  86. to the screen offset register. This causes the screen to jump up by one
  87.  
  88. row. However, it also causes whatever is off the bottom of the screen
  89.  
  90. (the next page!) to become visible...not a desireable effect.
  91.  
  92.  
  93. Easily fixed however. Draw the image you want to scroll, on the row that
  94.  
  95. will scroll on. So, when the screen offset is changed to scroll the screen
  96.  
  97. up, the new data is already there for all to see. Beautiful!!!
  98.  
  99.  
  100. ----------- Scrolling A (up) --------------
  101.  
  102. OFFSET = 0
  103.  
  104. WHILE NOT FINISHED DO
  105.  
  106.   OFFSET = OFFSET + 80
  107.  
  108.   DRAW TO ROW 200
  109.  
  110.   SET VGA OFFSET = OFFSET
  111.  
  112. END WHILE
  113.  
  114. -------------------------------------------
  115.  
  116.  
  117. Bzzzzz! Wrong! This works fine, until you have scrolled down to the
  118.  
  119. bottom of page 4. Because you're effectively off the bottom of the VGA
  120.  
  121. window (starting at segment A000h), you can't write to the rest of the
  122.  
  123. VGA memory (if there is any - only SVGA's have more than 256K on board
  124.  
  125. memory) and so, you'll be viewing garbage.
  126.  
  127.  
  128. No problem. The way around it is to only use two pages!!! "What?" I hear
  129.  
  130. you say. In fact, by using only two pages for scrolling, you gain two
  131.  
  132. major advantages: page flipping (because you're only using two pages for
  133.  
  134. the actual scrolling, you can use the spare two to perform page flipping)
  135.  
  136. and infinite scroll regions.
  137.  
  138.  
  139. You perform the infinite scrolling in exactly the same way as before, with
  140.  
  141. two minor additions: after changing the offset register, you copy the row
  142.  
  143. just scrolled on to the row just scrolled off. Also, after you have scrolled
  144.  
  145. a full page, you reset the offset to the top of the original page.
  146.  
  147.  
  148. ----------- Scrolling B (up) --------------
  149.  
  150. OFFSET = 0
  151.  
  152. WHILE NOT FINISHED DO
  153.  
  154.   OFFSET = OFFSET + 80
  155.  
  156.   IF OFFSET >= (200 * 80) THEN OFFSET = 0
  157.  
  158.   DRAW TO ROW 200
  159.  
  160.   SET VGA OFFSET = OFFSET
  161.  
  162.   DRAW TO ROW -1 (was row 0 before scroll)
  163.  
  164. END WHILE
  165.  
  166. -------------------------------------------
  167.  
  168.  
  169. Ok, so that's how to do vertical scrolling, now on with horizontal scrolling.
  170.  
  171.  
  172.  
  173.  
  174. --------------------
  175.  
  176. HORIZONTAL SCROLLING
  177.  
  178. --------------------
  179.  
  180. Horizontal scrolling is essentially the same as vertical scrolling, all
  181.  
  182. you do is increment or decrement the VGA offset register by 1 instead of
  183.  
  184. 80 as with vertical scrolling.
  185.  
  186.  
  187. However, horizontal scrolling is complicated by two things
  188.  
  189.  
  190.   1. Incrementing the offset register by one actually scrolls by FOUR
  191.  
  192.      pixels (and there are FOUR planes on the VGA, what a coincidence)
  193.  
  194.  
  195.   2. You can't draw the image off the screen and then scroll it on
  196.  
  197.      because of the way the VGA wraps to the next row every 80 bytes
  198.  
  199.      (80 bytes * 4 planes = 320 pixels), if you tried it, you would
  200.  
  201.      actually be drawing to the other side of the screen (which is
  202.  
  203.      entirely visible)
  204.  
  205.  
  206. I'll solve these problems one at a time.
  207.  
  208.  
  209. Firstly, to get the VGA to scroll by only one pixel you use the horizontal
  210.  
  211. pixel panning (HPP) register. This register resides at
  212.  
  213.  
  214.   PORT:     3C0H
  215.  
  216.   INDEX:    13h
  217.  
  218.  
  219. and in real life, you use it like this
  220.  
  221.  
  222. ----------------- Pixel Panning ---------------
  223.  
  224. IN PORT 3DAH (this clears an internal
  225.  
  226.   flip-flop of the VGA)
  227.  
  228. OUT 13H TO PORT 3C0H
  229.  
  230. OUT value TO PORT 3C0H (where "value" is the
  231.  
  232.   number of pixels to offset)
  233.  
  234. -----------------------------------------------
  235.  
  236.  
  237. To implement smooth horizontal scrolling, you would do the following:
  238.  
  239.  
  240. -------------- Horizontal Scrolling ------------
  241.  
  242. FOR X = 0 TO 319 DO
  243.  
  244.   SET HPP TO ( X MOD 4 )
  245.  
  246.   SET VGA OFFSET TO ( X/4 )
  247.  
  248. END FOR
  249.  
  250. ------------------------------------------------
  251.  
  252.  
  253. Okay, no problem at all (although I think you might have to fiddle
  254.  
  255. around with the HPP a bit to get it right...try different values and
  256.  
  257. see what works :).
  258.  
  259.  
  260. So, the next problem is with drawing the images off the screen where
  261.  
  262. they aren't visible and then scrolling them on!!! As it turns out,
  263.  
  264. there's yet ANOTHER register to accomplish this. This one's called the
  265.  
  266. offset register (no, not the one I was talking about before, that one
  267.  
  268. was actually the "start address" register) and it's at
  269.  
  270.  
  271.   PORT:     3D4H/3D5H
  272.  
  273.   OFFSET:   13H
  274.  
  275.  
  276. and here's how to use it
  277.  
  278.  
  279. -------------- Offset Register ---------------
  280.  
  281. OUT 13H TO PORT 3D4H
  282.  
  283. OUT value TO PORT 3D5H
  284.  
  285. ----------------------------------------------
  286.  
  287.  
  288. Now, what my VGA reference says is that this register holds the number
  289.  
  290. of bytes (not pixels) difference between the start address of each row.
  291.  
  292. So, in X-mode it normally contains the value 80 (as we remember,
  293.  
  294. 80 bytes * 4 planes = 320 pixels). This register does not affect the
  295.  
  296. VISIBLE width of the display, only the difference between addresses on
  297.  
  298. each row.
  299.  
  300.  
  301. When we scroll horizontally, we need a little bit of extra working space
  302.  
  303. so we can draw off the edge of the screen.
  304.  
  305.  
  306. Perhaps a little diagram will clarify it. The following picture is of a
  307.  
  308. standard X-mode addressing scheme with the OFFSET register set to 80.
  309.  
  310.  
  311.       ROW    OFFSET
  312.  
  313.       0         0 ========================
  314.  
  315.       1        80 [                      ]
  316.  
  317.       2       160 [                      ]
  318.  
  319.       ..       .. [       VISIBLE        ]
  320.  
  321.                   [        SCREEN        ]
  322.  
  323.                   [                      ]
  324.  
  325.                   [                      ]
  326.  
  327.       ..       .. [                      ]
  328.  
  329.       199   15920 ========================
  330.  
  331.  
  332. and the next diagram is of a modified addressing scheme with the OFFSET
  333.  
  334. register set to 82 (to give us 4 extra pixels on each side of the screen)
  335.  
  336.  
  337. ROW    OFFSET
  338.  
  339. 0         0 ------========================------
  340.  
  341. 1        82 |   V [                      ]   V |
  342.  
  343. 2       164 |   I [                      ]   I |
  344.  
  345. ..       .. | N S [      VISIBLE         ] N S |
  346.  
  347.             | O I [       SCREEN         ] O I |
  348.  
  349.             | T B [                      ] T B |
  350.  
  351.             |   L [                      ]   L |
  352.  
  353. ..       .. |   E [                      ]   E |
  354.  
  355. 199   16318 ------========================------
  356.  
  357.  
  358. Beautiful!!!
  359.  
  360.  
  361. As with vertical scrolling, however, you still have the problem of when
  362.  
  363. you reach the bottom of page 4...and it's fixed in the same manner.
  364.  
  365.  
  366. I haven't actually managed to get infinite horizontal scrolling working,
  367.  
  368. but the method I have just stated will give you a horizontal scrolling
  369.  
  370. range of over 200 screens!!!! So if you need more (which is extremely
  371.  
  372. unlikely), figure it out yourself.
  373.  
  374.  
  375.  
  376. ------------------
  377.  
  378. COMBINED SCROLLING
  379.  
  380. ------------------
  381.  
  382. To do both horizontal and vertical scrolling, all you have to do is combine
  383.  
  384. the two methods with a few little extras (it's always the way isn't it).
  385.  
  386.  
  387. You have to start off with the original screen on the current page and the
  388.  
  389. next page as well. When you scroll horizontally, you have to draw the edge
  390.  
  391. that's coming in to the screen to BOTH pages (that means you'll be drawing
  392.  
  393. the incoming edge twice, once for each page). You do this so that when you
  394.  
  395. have scrolled vertically down through a complete page, you can jump back
  396.  
  397. to the first page and it will (hopefully) have an identical copy, and you
  398.  
  399. can then continue scrolling again.
  400.  
  401.  
  402. I'm sorry about this being so confusing but it's a bit difficult to explain.
  403.  
  404.  
  405.  
  406.  
  407.  
  408.  
  409. ********************************************************************************
  410.  
  411. *                            STANDARD VGA SCROLLING                            *
  412.  
  413. ********************************************************************************
  414.  
  415. Without X-mode, there is no easy way to do scrolling using the VGA hardware.
  416.  
  417. So basically, you have to resort to redrawing the entire screen for every
  418.  
  419. frame. Several popular games (Raptor and Mortal Kombat spring to mind)
  420.  
  421. utilise this method with excellent effect, so it is quite effective.
  422.  
  423.  
  424. Basically all you do to implement this is redraw the screen every frame
  425.  
  426. with a slightly different offset into the "map".
  427.  
  428.  
  429. The following bit of pseudo-code will scroll down and to the right
  430.  
  431. through the map.
  432.  
  433.  
  434. ------------- Standard Scrolling ---------------
  435.  
  436. X = 0
  437.  
  438. Y = 0
  439.  
  440. WHILE NOT FINISHED DO
  441.  
  442.   DRAW TO SCREEN( 0, 0 ) FROM MAP( X, Y )
  443.  
  444.   X = X + 1
  445.  
  446.   Y = Y + 1
  447.  
  448. END WHILE
  449.  
  450. ------------------------------------------------
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457. ********************************************************************************
  458.  
  459. *                              PARALLAX SCROLLING                              *
  460.  
  461. ********************************************************************************
  462.  
  463. Parallax scrolling is when the "world" appears to have different levels
  464.  
  465. of perspective. That is, images further away from the viewer move
  466.  
  467. proportionately slower than images closer to the screen.
  468.  
  469.  
  470. To implement parallax scrolling, you need two or more "maps". You start
  471.  
  472. from the most distant map and end with the closest map. When you scroll,
  473.  
  474. you offset the map furthest away by the smallest value and the map
  475.  
  476. closest to you by the largest value.
  477.  
  478.  
  479. The following pseudo-code implements a 3 level parallax scrolling world,
  480.  
  481. scrolling (as above) down to the right.
  482.  
  483.  
  484. --------------- Parallax Scrolling ------------------
  485.  
  486. X = 0
  487.  
  488. Y = 0
  489.  
  490. WHILE NOT FINISHED DO
  491.  
  492.   DRAW TO SCREEN( 0, 0 ) USING MAP_FAR AT ( X/4, Y/4 )
  493.  
  494.   DRAW TO SCREEN( 0, 0 ) USING MAP_MEDIUM AT ( X/2, Y/2 )
  495.  
  496.   DRAW TO SCREEN( 0, 0 ) USING MAP_NEAR AT ( X, Y )
  497.  
  498.   X = X + 4
  499.  
  500.   Y = Y + 4
  501.  
  502. END WHILE
  503.  
  504. -----------------------------------------------------
  505.  
  506.  
  507. Obviously, with parallax scrolling, each successive map shouldn't delete
  508.  
  509. the previous map entirely. So you'll have to draw the maps using some
  510.  
  511. sort of masking (masking being where you can see through the background
  512.  
  513. colour to what was there previously).
  514.  
  515.  
  516.  
  517. ********************************************************************************
  518.  
  519. *                                  DISCLAIMER                                  *
  520.  
  521. ********************************************************************************
  522.  
  523. I'm sorry if any of this is confusing, but hey that's half the fun of it -
  524.  
  525. figuring out what the hell I'm raving on about :)
  526.  
  527.  
  528. So, if you can figure it out, have fun and make games (preferably good ones!)
  529.  
  530.  
  531. Later,
  532.  
  533.       Kestrel => FORGE Software Australia
  534.  
  535.